package com.ruoyi.system.service.impl;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONUtil;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.OrderTypeEnum;
import com.ruoyi.common.enums.PayOrderTypeEnum;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.common.utils.OrderNoUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.hospital.domain.*;
import com.ruoyi.hospital.mapper.*;
import com.ruoyi.system.domain.PayOrder;
import com.ruoyi.system.domain.po.*;
import com.ruoyi.system.domain.vo.*;
import com.ruoyi.system.mapper.PayOrderMapper;
import com.ruoyi.system.service.PetHospitalService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class PetHospitalServiceImpl implements PetHospitalService {

    @Resource
    private CustomerPetMapper customerPetMapper;

    @Resource
    private CustomerMapper customerMapper;

    @Resource
    private CustomerBalanceMapper customerBalanceMapper;

    @Resource
    private CustomerRechargeRecordMapper customerRechargeRecordMapper;

    @Resource
    private ConsultationRecordMapper consultationMapper;

    @Resource
    private OrderNoUtils orderNoUtils;

    @Resource
    private PrescriptionMapper prescriptionMapper;

    @Resource
    private PrescriptionDetailMapper prescriptionDetailMapper;

    @Resource
    private InspectionRecordMapper inspectionRecordMapper;

    @Resource
    private RedisTemplate<String, String> redisTemplate;

    @Resource
    private MaterielOutboundRecordMapper materielOutboundRecordMapper;

    @Resource
    private MaterielMapper materielMapper;

    @Resource
    private PayOrderMapper payOrderMapper;

    @Resource
    private InspectionMapper inspectionMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult consultation(ConsultationPO consultationPO) {
        LoginUser user = SecurityUtils.getLoginUser();
        Customer customer = BeanUtil.copyProperties(consultationPO.getCustomerPO(), Customer.class);
        CustomerPet pet = BeanUtil.copyProperties(consultationPO.getCustomerPetPO(), CustomerPet.class);
        Long tenantId = user.getUser().getTenantId();
        if (customer.getId() == null) {
            //验证手机号是否重复
            CustomerSpinnerVO customerSpinnerVO = customerMapper.queryCustomerByPhone(consultationPO.getCustomerPO().getPhone(), user.getUser().getTenantId());
            if (customerSpinnerVO != null && customerSpinnerVO.getPhone().equals(consultationPO.getCustomerPO().getPhone())) {
                return AjaxResult.error("手机号已存在");
            }
            customer.setTenantId(tenantId);
            customerMapper.insertCustomer(customer);
            pet.setCustomerId(customer.getId());


            customerPetMapper.insertCustomerPet(pet);
        }
        if (pet.getId() != null) {
            customerPetMapper.updateCustomerPet(pet);
        }
        ConsultationRecord consultationRecord = new ConsultationRecord();
        consultationRecord.setConsultationNo(orderNoUtils.generatedOrderNo(OrderTypeEnum.就诊单));
        consultationRecord.setPetId(pet.getId());
        consultationRecord.setCustomerId(customer.getId());
        consultationRecord.setSymptom(consultationPO.getSymptom());
        consultationRecord.setConsultationDoctorId(consultationPO.getDoctorId());
        consultationRecord.setDeptId(consultationPO.getDeptId());
        consultationRecord.setTenantId(tenantId);
        consultationRecord.setCreateBy(user.getUsername());
        consultationMapper.insertConsultationRecord(consultationRecord);
        // TODO: 2023/6/9 消息通知 对应医生 将医生界面 主动刷新 待就医的宠物信息
        return AjaxResult.success("已挂号，请前往对应科室等待叫号就诊！");
    }

    @Override
    public AjaxResult queryCustomerByPhone(String phone) {
        LoginUser user = SecurityUtils.getLoginUser();
        CustomerSpinnerVO customerSpinnerVO = customerMapper.queryCustomerByPhone(phone, user.getUser().getTenantId());
        if (customerSpinnerVO == null) {
            return AjaxResult.success();
        }
        if (customerSpinnerVO.getDelFlag().equals(Boolean.TRUE)) {
            return AjaxResult.error("客户信息异常！请处理后挂号");
        }
        CustomerPet pet = new CustomerPet();
        pet.setCustomerId(customerSpinnerVO.getCustomerId());
        pet.setTenantId(user.getUser().getTenantId());
        List<CustomerPetVO> customerPets = customerPetMapper.selectCustomerPetListByCustomerPhone(pet);
        customerSpinnerVO.setCustomerPetList(customerPets);
        return AjaxResult.success(customerSpinnerVO);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult recharge(CustomerRechargePO consultationPO) {
        LoginUser user = SecurityUtils.getLoginUser();

        CustomerSpinnerVO customer = customerMapper.queryCustomerByPhone(consultationPO.getCustomerPhone(), user.getUser().getTenantId());
        if (customer == null || customer.getDelFlag()) {
            return AjaxResult.error("客户信息异常！请处理后充值");
        }
        CustomerRechargeRecord rechargeRecord = new CustomerRechargeRecord();
        rechargeRecord.setRechargeNo(orderNoUtils.generatedOrderNo(OrderTypeEnum.充值记录单));
        rechargeRecord.setTenantId(user.getUser().getTenantId());
        rechargeRecord.setCustomerId(customer.getCustomerId());
        rechargeRecord.setBalance(consultationPO.getRechargeAmount());
        rechargeRecord.setRechargeType(consultationPO.getRechargeType());
        rechargeRecord.setRechargeTime(new Date());
        rechargeRecord.setIntegral(consultationPO.getRechargeAmount().longValue());
        rechargeRecord.setRemark(consultationPO.getRemarks());
        int i = customerRechargeRecordMapper.insertCustomerRechargeRecord(rechargeRecord);
        BigDecimal balance = BigDecimal.ZERO;
        if (i > 0) {
            CustomerBalance customerBalance = customerBalanceMapper.selectCustomerBalanceByCustomerId(customer.getCustomerId());
            if (customerBalance == null) {
                customerBalance = new CustomerBalance();
                customerBalance.setTenantId(user.getUser().getTenantId());
                customerBalance.setCustomerId(customer.getCustomerId());
                customerBalance.setBalance(consultationPO.getRechargeAmount());
                // TODO: 2023/6/25 会员登记、会员结算方式
                customerBalance.setLevel(1);
                customerBalance.setSettlementType(1);
                customerBalance.setIntegral(consultationPO.getRechargeAmount().longValue());
                customerBalance.setVersion(1L);
                //余额
                customerBalanceMapper.insertCustomerBalance(customerBalance);
                //如果是会员 //修改会员类型
                if (consultationPO.isVip()) {
                    customer.setCustomerId(customerBalance.getId());
                    customer.setCustomerType(1);
                    customerMapper.updateCustomer(BeanUtil.copyProperties(customer, Customer.class));
                }
                balance = consultationPO.getRechargeAmount();
            } else {
                balance = customerBalance.getBalance().add(consultationPO.getRechargeAmount());

                Date currentTime = new Date();
                customerBalanceMapper.updateBalance(customerBalance.getId(),
                        consultationPO.getRechargeAmount(),
                        rechargeRecord.getIntegral(),
                        customerBalance.getVersion(),
                        user.getUsername(), currentTime,
                        customerBalance.getLevel());
            }
        }
        return AjaxResult.success("充值成功，当前余额:" + balance.stripTrailingZeros().toPlainString());
    }

    @Override
    public List<ConsultationRecordVO> queryConsultationRecord(ConsultationRecordPO consultationRecordPO) {
        List<ConsultationRecordVO> list = consultationMapper.queryConsultationRecord(consultationRecordPO);
        if (CollUtil.isEmpty(list)) {
            return list;
        }
        List<Long> consultationIds = list.stream().map(ConsultationRecordVO::getConsultationId).distinct().collect(Collectors.toList());
        List<PrescriptionVO> prescriptionList = prescriptionMapper.selectPrescriptionByIds(consultationIds);
        if (CollUtil.isEmpty(prescriptionList)) {
            return list;
        }
        Map<Long, ConsultationRecordVO> consultationRecordVOMap = list.stream().collect(Collectors.toMap(ConsultationRecordVO::getConsultationId, c -> c));
        Map<Long, PrescriptionVO> map = prescriptionList.stream().collect(Collectors.toMap(PrescriptionVO::getId, c -> c));
        List<Long> prescriptionIds = prescriptionList.stream().map(PrescriptionVO::getId).distinct().collect(Collectors.toList());
        List<PrescriptionDetail> details = prescriptionDetailMapper.queryAllByPrescriptionId(prescriptionIds);
        Map<Long, List<PrescriptionDetail>> detailMap = details.stream().collect(Collectors.groupingBy(PrescriptionDetail::getPrescriptionId));
        List<InspectionRecordVO> inspectionRecordList = inspectionRecordMapper.selectInspectionRecordListByConsultationIds(consultationIds);
        Map<Long, List<InspectionRecordVO>> inspectionRecordMap = inspectionRecordList.stream().collect(Collectors.groupingBy(InspectionRecordVO::getConsultationId));
        map.forEach((k, v) -> {
            v.setPrescriptionDetail(detailMap.getOrDefault(k, null));
            v.setInspectionRecordList(inspectionRecordMap.getOrDefault(k, null));
        });
        Map<Long, List<PrescriptionVO>> listMap = map.values().stream().collect(Collectors.groupingBy(PrescriptionVO::getConsultationId));
        consultationRecordVOMap.forEach((k, v) -> v.setPrescription(listMap.getOrDefault(k, null)));
        return list;
    }

    /**
     * 开处方
     *
     * @param prescriptionPO 处方信息
     * @return 客户信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult prescribing(ConsultationPrescriptionPO prescriptionPO) {
        LoginUser user = SecurityUtils.getLoginUser();
        ConsultationRecord consultationRecord = consultationMapper.selectConsultationRecordById(prescriptionPO.getConsultationId());
        Customer customerSpinnerVO = customerMapper.selectCustomerById(consultationRecord.getCustomerId());
        Date date = new Date();
        if (prescriptionPO.getPrescriptionType() == 1) {
            //住院处方->修改就诊单状态为住院治疗
            consultationRecord.setConsultationStatus(2);
            consultationRecord.setUpdateBy(user.getUsername());
            consultationRecord.setUpdateTime(date);
            consultationMapper.updateConsultationRecord(consultationRecord);
        } else {
            //修改就诊单状态为开处方完成
            consultationRecord.setConsultationStatus(1);
            consultationRecord.setUpdateBy(user.getUsername());
            consultationRecord.setUpdateTime(date);
            consultationMapper.updateConsultationRecord(consultationRecord);
        }
        Prescription prescription = BeanUtil.copyProperties(prescriptionPO, Prescription.class);
        Long tenantId = user.getUser().getTenantId();
        Long deptId = user.getDeptId();
        prescription.setTenantId(tenantId);
        prescription.setDeptId(deptId);
        String orderNo = orderNoUtils.generatedOrderNo(OrderTypeEnum.处方单);
        String username = user.getUsername();
        prescription.setPrescriptionNo(orderNo);
        prescription.setConsultationId(consultationRecord.getId());
        prescription.setPrescriptionCode(consultationRecord.getConsultationNo());
        prescription.setDoctorId(user.getUserId());
        prescription.setCustomerId(consultationRecord.getCustomerId());
        prescription.setPetId(consultationRecord.getPetId());
        prescription.setCreateBy(username);
        prescriptionMapper.insertPrescription(prescription);

        if (CollUtil.isNotEmpty(prescriptionPO.getPrescriptionDetail()) || CollUtil.isNotEmpty(prescriptionPO.getInspectionRecordList())) {

            if (CollUtil.isNotEmpty(prescriptionPO.getPrescriptionDetail())) {
                List<PrescriptionDetail> detailList = BeanUtil.copyToList(prescriptionPO.getPrescriptionDetail(), PrescriptionDetail.class);
                detailList.forEach(detail -> {
                    detail.setTenantId(tenantId);
                    detail.setDeptId(deptId);
                    detail.setPrescriptionCode(orderNo);
                    detail.setPrescriptionId(prescription.getId());
                    detail.setCreateBy(username);
                    detail.setCreateTime(date);
                });

                prescriptionDetailMapper.insertBatch(detailList);

                List<MaterielOutboundRecord> outboundRecordList = new ArrayList<>();
                //出库单
                detailList.forEach(c -> {
                    MaterielOutboundRecord outboundRecord = new MaterielOutboundRecord();
                    outboundRecord.setMaterielId(c.getMaterielId());
                    outboundRecord.setMaterielCode(c.getMaterielCode());
                    outboundRecord.setCustomerId(consultationRecord.getCustomerId());
                    outboundRecord.setCustomerPhone(customerSpinnerVO.getPhone());
                    outboundRecord.setPrescriptionId(prescription.getId());
                    outboundRecord.setPrescriptionDetailId(c.getId());
                    outboundRecord.setPrescriptionCode(prescription.getPrescriptionCode());
                    outboundRecord.setNumber(c.getPlanNum());
                    outboundRecord.setOutboundType(1);
                    outboundRecord.setOutboundStatus(0);
                    outboundRecord.setCreateBy(username);
                    outboundRecord.setCreateTime(date);
                    outboundRecordList.add(outboundRecord);
                });
                materielOutboundRecordMapper.insertBatch(outboundRecordList);
            }

            if (CollUtil.isNotEmpty(prescriptionPO.getInspectionRecordList())) {
                //新增的检查项目
                List<InspectionRecordPO> inspectionRecordPOS = prescriptionPO.getInspectionRecordList().stream().filter(c -> c.getId() == null).collect(Collectors.toList());
                if (CollUtil.isNotEmpty(inspectionRecordPOS)) {
                    List<InspectionRecord> inspectionRecordPOList = BeanUtil.copyToList(inspectionRecordPOS, InspectionRecord.class);
                    inspectionRecordPOList.forEach(detail -> {
                        detail.setPetId(consultationRecord.getPetId());
                        detail.setCustomerId(consultationRecord.getCustomerId());
                        detail.setInspectionStatus(1);
                        detail.setConsultationId(prescriptionPO.getConsultationId());
                        detail.setConsultationNo(consultationRecord.getConsultationNo());
                        detail.setCreateBy(username);
                        detail.setTenantId(tenantId);
                        detail.setDeptId(deptId);
                        detail.setPrescriptionCode(orderNo);
                        detail.setPrescriptionId(prescription.getId());
                        detail.setCreateTime(date);
                    });
                    inspectionRecordMapper.insertBatch(inspectionRecordPOList);
                }
            }
        }
        return AjaxResult.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult prescribingCache(ConsultationPrescriptionPO prescriptionPO) {
        LoginUser user = SecurityUtils.getLoginUser();

        Integer consultationStatus = consultationMapper.selectConsultationRecordById(prescriptionPO.getConsultationId()).getConsultationStatus();
        if (consultationStatus != 3) {
            //获取缓存中的就诊单
            String orderKey = OrderTypeEnum.处方单.getType() + ":" + user.getUser().getTenantId() + ":" + prescriptionPO.getConsultationId();
            redisTemplate.opsForValue().set(orderKey, JSONUtil.toJsonStr(prescriptionPO));
        }
        return AjaxResult.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult getPrescribingCache(Long consultationId) {
        LoginUser user = SecurityUtils.getLoginUser();

        //获取缓存中的就诊单
        String orderKey = OrderTypeEnum.处方单.getType() + ":" + user.getUser().getTenantId() + ":" + consultationId;
        String prescription = redisTemplate.opsForValue().get(orderKey);
        if (CharSequenceUtil.isBlank(prescription)) {
            return AjaxResult.success();
        }
        ConsultationPrescriptionPO consultationPrescriptionPO = JSONUtil.toBean(prescription, ConsultationPrescriptionPO.class);
        return AjaxResult.success(consultationPrescriptionPO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult inspection(InspectionRecordPO prescriptionPO) {
        LoginUser user = SecurityUtils.getLoginUser();

        InspectionRecord inspectionRecord = inspectionRecordMapper.selectInspectionRecordById(prescriptionPO.getId());
        if (inspectionRecord.getInspectionStatus() == 3) {
            return AjaxResult.error("检查已结束");
        }
        InspectionRecord update = BeanUtil.copyProperties(prescriptionPO, InspectionRecord.class);
        update.setUpdateBy(user.getUsername());
        update.setInspectionStatus(1);
        update.setUpdateTime(new Date());
        int i = inspectionRecordMapper.updateInspectionRecord(update);
        return AjaxResult.success(i > 0);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult retail(RetailPO retailPO) {
        LoginUser user = SecurityUtils.getLoginUser();

        String userName = user.getUsername();
        Date date = new Date();
        Long customerId = null;
        CustomerSpinnerVO customerSpinnerVO = null;
        if (CharSequenceUtil.isNotBlank(retailPO.getCustomerPhone())) {
            customerSpinnerVO = customerMapper.queryCustomerByPhone(retailPO.getCustomerPhone(), user.getUser().getTenantId());
            if (customerSpinnerVO != null) {
                customerId = customerSpinnerVO.getCustomerId();
            }
        }

        final Long customerIdF = customerId;
        List<MaterielOutboundRecord> list = new ArrayList<>();
        retailPO.getRetailList().forEach(c -> {
            MaterielOutboundRecord outboundRecord = BeanUtil.copyProperties(c, MaterielOutboundRecord.class);
            outboundRecord.setCustomerPhone(retailPO.getCustomerPhone());
            outboundRecord.setUserId(retailPO.getUserId());
            outboundRecord.setRemark(retailPO.getRemarks());
            outboundRecord.setOutboundType(1);
            outboundRecord.setOutboundStatus(1);
            outboundRecord.setCreateBy(userName);
            outboundRecord.setCreateTime(date);
            outboundRecord.setCustomerId(customerIdF);
        });
        int i = materielOutboundRecordMapper.insertBatch(list);
        BigDecimal balance = BigDecimal.ZERO;
        List<Materiel> materielList = materielMapper.selectMaterielByIds(list.stream().map(MaterielOutboundRecord::getMaterielId).distinct().collect(Collectors.toList()));
        Map<Long, Materiel> materielMap = materielList.stream().collect(Collectors.toMap(Materiel::getId, c -> c));
        //会员价格
        if (customerSpinnerVO != null && customerSpinnerVO.getCustomerType() == 1) {
            balance = balance.add(list.stream().map(c -> materielMap.get(c.getMaterielId()).getMemberPrice().multiply(c.getNumber())).reduce(BigDecimal::add).get());
        } else {
            //零售价格
            balance = balance.add(list.stream().map(c -> materielMap.get(c.getMaterielId()).getRetailPrice().multiply(c.getNumber())).reduce(BigDecimal::add).get());
        }
        PayOrder payOrder = new PayOrder();
        //生成待支付订单
        payOrder.setAmount(balance.setScale(2, RoundingMode.HALF_UP));
        payOrder.setOrderNo(orderNoUtils.generatedOrderNo(OrderTypeEnum.支付订单));
        payOrder.setCustomerId(customerIdF);
        payOrder.setOrderType(PayOrderTypeEnum.零售.getType());
        payOrder.setTenantId(user.getUser().getTenantId());
        payOrder.setDeptId(user.getDeptId());
        payOrder.setCreateBy(userName);
        payOrder.setCreateTime(date);
        //待支付金额 =0 支付完成
        payOrder.setOrderStatus(2);
        payOrderMapper.insert(payOrder);
        return AjaxResult.success(i > 0);
    }

    /**
     * 查询待出库的出库单
     *
     * @param customerPhone 手机号
     * @return 出库单
     */
    @Override
    public AjaxResult queryOutboundOrder(String customerPhone, Date timeStart, Date timeEnd) {
        ConsultationRecordPO consultationRecordPO = new ConsultationRecordPO();
        consultationRecordPO.setCustomerPhone(customerPhone);
        List<ConsultationRecordVO> list = consultationMapper.queryConsultationRecordAndStatus(customerPhone, Collections.singletonList(1), timeStart, timeEnd);
        if (CollUtil.isEmpty(list)) {
            return AjaxResult.success(list);
        }
        List<Long> consultationIds = list.stream().map(ConsultationRecordVO::getConsultationId).distinct().collect(Collectors.toList());
        List<PrescriptionVO> prescriptionList = prescriptionMapper.selectPrescriptionByIds(consultationIds);
        if (CollUtil.isEmpty(prescriptionList)) {
            return AjaxResult.success(list);
        }
        List<ConsultationOutBoundVO> outBoundVOS = BeanUtil.copyToList(list, ConsultationOutBoundVO.class);

        Map<Long, ConsultationOutBoundVO> consultationRecordVOMap = outBoundVOS.stream().collect(Collectors.toMap(ConsultationOutBoundVO::getConsultationId, c -> c));
        Map<Long, PrescriptionVO> map = prescriptionList.stream().collect(Collectors.toMap(PrescriptionVO::getConsultationId, c -> c));
        List<Long> prescriptionIds = prescriptionList.stream().map(PrescriptionVO::getId).distinct().collect(Collectors.toList());

        //只查询对应检查单id的 处方明细
        List<MaterielOutboundRecordVO> outboundRecordList = materielOutboundRecordMapper.selectMaterielOutboundRecordListByPrescriptionIds(prescriptionIds);
        //筛选为出库的出库记录
        Map<Long, List<MaterielOutboundRecordVO>> outboundRecordMap = outboundRecordList.stream().filter(c -> c.getOutboundStatus() == 0).collect(Collectors.groupingBy(MaterielOutboundRecordVO::getPrescriptionId));
        List<InspectionRecordVO> inspectionRecordList = inspectionRecordMapper.selectInspectionRecordListByConsultationIds(consultationIds);
        //筛选已结束的检查项目
        Map<Long, List<InspectionRecordVO>> inspectionRecordMap = inspectionRecordList.stream().filter(c -> c.getInspectionStatus() == 1).collect(Collectors.groupingBy(InspectionRecordVO::getConsultationId));
        consultationRecordVOMap.forEach((k, v) -> {
            ConsultationOutBoundDetailVO vo = new ConsultationOutBoundDetailVO();
            PrescriptionVO orDefault = map.getOrDefault(k, new PrescriptionVO());
            vo.setOutboundRecordList(outboundRecordMap.getOrDefault(orDefault.getId(), null));
            vo.setInspectionRecordList(inspectionRecordMap.getOrDefault(k, null));
            v.setOutBoundDetailVO(vo);
        });
        return AjaxResult.success(outBoundVOS);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult outbound(InspectionOutboundPO inspectionOutboundPO) {
       BigDecimal actualAmount = inspectionOutboundPO.getActualAmount();

        LoginUser user = SecurityUtils.getLoginUser();
        Date date = new Date();
        ConsultationRecord consultationRecord = consultationMapper.selectConsultationRecordById(inspectionOutboundPO.getConsultationId());
        if (consultationRecord == null || consultationRecord.getConsultationStatus() == 3) {
            return AjaxResult.error("就诊单已过期");
        }
        Customer customerSpinnerVO = customerMapper.selectCustomerById(consultationRecord.getCustomerId());
        BigDecimal balance = BigDecimal.ZERO;

        if (CollUtil.isNotEmpty(inspectionOutboundPO.getInspectionList())) {
            List<InspectionRecord> inspectionRecord = inspectionRecordMapper.selectInspectionRecordByIds(inspectionOutboundPO.getInspectionList());
            boolean b = inspectionRecord.stream().anyMatch(c -> c.getInspectionStatus() == 0);
            if (b) {
                throw new GlobalException("未结束的项目不能结算");
            }
            boolean b2 = inspectionRecord.stream().anyMatch(c -> c.getInspectionStatus() == 3);
            if (b2) {
                throw new GlobalException("已结束的项目不能结算");
            }
            List<Inspection> inspections = inspectionMapper.selectInspectionByIds(inspectionRecord.stream().map(InspectionRecord::getInspectionId).distinct().collect(Collectors.toList()));
            Map<Long, BigDecimal> inspectionMap = inspections.stream().collect(Collectors.toMap(Inspection::getId, Inspection::getBalance));
            balance = balance.add(inspectionRecord.stream().map(c -> inspectionMap.get(c.getInspectionId()).multiply(new BigDecimal(c.getNumber()))).reduce(BigDecimal::add).get());
            inspectionRecordMapper.updateBatchStatus(inspectionOutboundPO.getInspectionList(), 2, user.getUsername());
        }
        if (CollUtil.isNotEmpty(inspectionOutboundPO.getList())) {
            List<Long> collect = inspectionOutboundPO.getList().stream().map(OutboundDetailPO::getId).collect(Collectors.toList());
            List<MaterielOutboundRecord> list = materielOutboundRecordMapper.selectMaterielOutboundRecordByIds(collect);
            list.forEach(c -> {
                MaterielOutboundRecord outboundRecord = BeanUtil.copyProperties(c, MaterielOutboundRecord.class);
                outboundRecord.setRemark(inspectionOutboundPO.getRemark());
                outboundRecord.setNumber(c.getNumber());
                outboundRecord.setOutboundStatus(1);
                outboundRecord.setUpdateBy(user.getUsername());
                outboundRecord.setUpdateTime(date);
                list.add(outboundRecord);
            });
            List<Materiel> materielList = materielMapper.selectMaterielByIds(list.stream().map(MaterielOutboundRecord::getMaterielId).distinct().collect(Collectors.toList()));
            Map<Long, Materiel> materielMap = materielList.stream().collect(Collectors.toMap(Materiel::getId, c -> c));
            //会员价格
            if (customerSpinnerVO.getCustomerType() == 1) {
                balance = balance.add(list.stream().map(c -> materielMap.get(c.getMaterielId()).getMemberPrice().multiply(c.getNumber())).reduce(BigDecimal::add).get());
            } else {
                //零售价格
                balance = balance.add(list.stream().map(c -> materielMap.get(c.getMaterielId()).getRetailPrice().multiply(c.getNumber())).reduce(BigDecimal::add).get());
            }
            materielOutboundRecordMapper.updateMaterielOutboundRecordNumber(list);
        }
        boolean subCustomerBalance = false;

        if (inspectionOutboundPO.getCustomerBalance()) {
            //是否扣除账号余额
            CustomerBalance customerBalance = customerBalanceMapper.selectCustomerBalanceByCustomerId(customerSpinnerVO.getCustomerId());
            if (customerBalance != null && customerBalance.getBalance().compareTo(BigDecimal.ZERO) > 0) {
                //余额大于等于 订单金额
                if (customerBalance.getBalance().compareTo(balance) >= 0) {
                    BigDecimal subtract = customerBalance.getBalance().subtract(balance);
                    customerBalanceMapper.updateBalance(customerBalance.getId(), subtract, subtract.longValue(), customerBalance.getVersion(), user.getUsername(), date, customerBalance.getLevel());
                    //支付金额为0
                    balance = BigDecimal.ZERO;
                } else {
                    //不够扣的，扣光余额，
                    balance = balance.subtract(customerBalance.getBalance());
                    customerBalanceMapper.updateBalance(customerBalance.getId(), BigDecimal.ZERO, balance.longValue(), customerBalance.getVersion(), user.getUsername(), date, customerBalance.getLevel());
                }
                subCustomerBalance = true;
            }
        }

        //查询是否存在未支付完的 支付订单
        PayOrder queryOrder = new PayOrder();
        queryOrder.setCustomerId(customerSpinnerVO.getCustomerId());
        queryOrder.setOrderType(PayOrderTypeEnum.处方就诊.getType());
        queryOrder.setBusinessId(consultationRecord.getId());
        PayOrder payOrder = payOrderMapper.queryOrder(queryOrder);
        if (payOrder == null) {
            payOrder = new PayOrder();
            //生成待支付订单
            payOrder.setAmount(balance.setScale(2, RoundingMode.HALF_UP));
            //存入实际支付金额
            payOrder.setPayAmount(inspectionOutboundPO.getActualAmount().setScale(2, RoundingMode.HALF_UP));
            payOrder.setOrderNo(orderNoUtils.generatedOrderNo(OrderTypeEnum.支付订单));
            payOrder.setCustomerId(customerSpinnerVO.getId());
            payOrder.setOrderType(PayOrderTypeEnum.处方就诊.getType());
            payOrder.setBusinessId(consultationRecord.getId());
            payOrder.setTenantId(user.getUser().getTenantId());
            payOrder.setDeptId(user.getDeptId());
            payOrder.setCreateBy(user.getUsername());
            payOrder.setCreateTime(date);
            //待支付金额 >0
            if (balance.compareTo(BigDecimal.ZERO) > 0) {
                //待支付金额 == 订单金额，待支付
                if (subCustomerBalance) {
                    payOrder.setOrderStatus(3);
                } else {
                    payOrder.setOrderStatus(1);
                }
            } else if (balance.compareTo(BigDecimal.ZERO) == 0) {
                //待支付金额 =0 支付完成
                payOrder.setOrderStatus(2);
            }
            payOrderMapper.insert(payOrder);
        } else {
            payOrder.setAmount(payOrder.getAmount().add(balance));
            payOrder.setPayAmount(payOrder.getPayAmount().add(actualAmount));

            payOrderMapper.update(payOrder);
        }
        //修改就诊单状态 为已结束
        consultationRecord.setConsultationStatus(3);
        int i = consultationMapper.updateConsultationRecord(consultationRecord);
        return AjaxResult.success(i > 0);
    }

}
